package mesh

import (
	"net/http"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"

	"cgs-server/helper"
	"cgs-server/server"
	"cgs-server/server/category"
)

func init() {
	//server.Handle(http.MethodGet, "/api/Mesh/List", List, server.ListMesh)
	server.Get("/api/Mesh/List", List, "获取模型列表", server.Login)
}

// List returns the mesh list.
func List(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	// todo 加一个过滤条件 type

	modelType := r.Form["Type"]

	db, err := server.Mongo()
	if err != nil {
		helper.WriteJSON(w, server.Result{
			Code: 300,
			Msg:  err.Error(),
		})
		return
	}

	// get all the categories
	filter := bson.M{
		"Type": "Mesh",
	}
	categories := []category.Model{}
	db.FindMany(server.CategoryCollectionName, filter, &categories)

	docs := bson.A{}

	opts := options.FindOptions{
		Sort: bson.M{
			"_id": -1,
		},
	}

	user, _ := server.GetCurrentUser(r)

	if user == nil {
		helper.WriteJSON(w, server.Result{
			Code: 300,
			Msg:  "permission denied",
		})
		return
	}

	filter1 := bson.M{
		"$or": bson.A{
			bson.M{
				"UserID": user.ID,
			},
			bson.M{
				"isInternal": true,
			},
		},
	}

	if user.Name == "Administrator" {
		filter2 := bson.M{
			"UserID": bson.M{
				"$exists": 0,
			},
		}
		filter1 = bson.M{
			"$or": bson.A{
				filter1,
				filter2,
			},
		}
	}

	if len(modelType) > 0 {
		filter1 = bson.M{
			"$and": bson.A{
				filter1,
				bson.M{
					"Type": bson.M{
						"$in": modelType,
					},
				},
			},
		}
	}

	db.FindMany(server.MeshCollectionName, filter1, &docs, &opts)

	list := []Model{}
	for _, i := range docs {
		doc := i.(primitive.D).Map()
		categoryID := ""
		categoryName := ""

		if doc["Category"] != nil {
			for _, category := range categories {
				if category.ID == doc["Category"].(string) {
					categoryID = category.ID
					categoryName = category.Name
					break
				}
			}
		}

		thumbnail, _ := doc["Thumbnail"].(string)

		isInternal := false
		if doc["isInternal"] != nil {
			isInternal = doc["isInternal"].(bool)
		}

		info := Model{
			ID:           doc["_id"].(primitive.ObjectID).Hex(),
			Name:         doc["Name"].(string),
			CategoryID:   categoryID,
			CategoryName: categoryName,
			TotalPinYin:  helper.PinYinToString(doc["TotalPinYin"]),
			FirstPinYin:  helper.PinYinToString(doc["FirstPinYin"]),
			Type:         doc["Type"].(string),
			URL:          doc["Url"].(string),
			AddTime:      doc["AddTime"].(primitive.DateTime).Time(),
			// CreateTime:   doc["CreateTime"].(primitive.DateTime).Time(),
			// UpdateTime:   doc["UpdateTime"].(primitive.DateTime).Time(),
			Thumbnail:  thumbnail,
			IsInternal: isInternal,
		}

		list = append(list, info)
	}

	helper.WriteJSON(w, server.Result{
		Code: 200,
		Msg:  "Get Successfully!",
		Data: list,
	})
}
